package com.jinly.ryder.deploy.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jinly.ryder.common.utils.DESUtil;
import com.jinly.ryder.common.utils.FileUtil;
import com.jinly.ryder.deploy.dao.DeployConfigFileMapper;
import com.jinly.ryder.deploy.dao.entity.DeployConfigFileDO;
import com.jinly.ryder.deploy.service.DeployConfigFileService;
import com.jinly.ryder.deploy.service.mapping.DeployConfigFileMapping;
import com.jinly.ryder.deploy.service.model.ConfigFileType;
import com.jinly.ryder.deploy.service.model.DeployConfigFile;
import com.jinly.ryder.deploy.service.model.DeployFileType;
import com.jinly.ryder.manage.config.SecretProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
@RequiredArgsConstructor
public class DeployConfigFileServiceImpl implements DeployConfigFileService {

    private final DeployConfigFileMapper deployConfigFileMapper;
    private final DeployConfigFileMapping deployConfigFileMapping;
    private final SecretProperties secretProperties;

    @Override
    public void saveConfigFile(DeployConfigFile deployConfigFile) {
        encrypt(deployConfigFile);
        if (deployConfigFile.getId() == null) {
            deployConfigFileMapper.insert(deployConfigFileMapping.toEntity(deployConfigFile));
        } else {
            deployConfigFileMapper.updateById(deployConfigFileMapping.toEntity(deployConfigFile));
        }
    }

    private void encrypt(DeployConfigFile deployConfigFile) {
        if (deployConfigFile.getFileType() == ConfigFileType.TEXT) {
            String text = new String(deployConfigFile.getFileContent());
            Pattern p = Pattern.compile("ENC\\((.+?)\\)");
            Matcher m = p.matcher(text);
            String result = text;
            while (m.find()) {
                String placeholder = m.group(0);
                String plainText = placeholder.substring(4, placeholder.length() - 1);
                String cipherText = DESUtil.encrypt(plainText, secretProperties.getSecretKey());
                result = result.replace(placeholder, "DEC(" + cipherText + ")");
            }
            deployConfigFile.setFileContent(result.getBytes());
        }
    }

    private void decrypt(DeployConfigFile deployConfigFile) {
        if (deployConfigFile.getFileType() == ConfigFileType.TEXT) {
            String text = new String(deployConfigFile.getFileContent());
            Pattern p = Pattern.compile("DEC\\((.+?)\\)");
            Matcher m = p.matcher(text);
            String result = text;
            while (m.find()) {
                String placeholder = m.group(0);
                String cipherText = placeholder.substring(4, placeholder.length() - 1);
                String plainText = DESUtil.decrypt(cipherText, secretProperties.getSecretKey());
                result = result.replace(placeholder, plainText);
            }
            deployConfigFile.setFileContent(result.getBytes());
        }
    }

    @Override
    public void deleteConfigFile(Integer fileId) {
        deployConfigFileMapper.deleteById(fileId);
    }

    @Override
    public List<DeployConfigFile> queryConfigFile(Integer deployGroupId, boolean hasContent) {
        Wrapper<DeployConfigFileDO> queryWrapper = new QueryWrapper<DeployConfigFileDO>().lambda()
                .select(DeployConfigFileDO.class, i -> hasContent ? true : !"file_content".equals(i.getColumn()))
                .eq(DeployConfigFileDO::getDeployGroupId, deployGroupId);
        return deployConfigFileMapping.toModelList(deployConfigFileMapper.selectList(queryWrapper));
    }

    /**
     * 获取解密后的配置文件
     *
     * @param fileId
     * @return
     */
    @Override
    public DeployConfigFile getDecryptConfigFile(Integer fileId) {
        DeployConfigFile configFile = getConfigFile(fileId);
        decrypt(configFile);
        return configFile;
    }

    @Override
    public DeployConfigFile getConfigFile(Integer fileId) {
        return deployConfigFileMapping.toModel(deployConfigFileMapper.selectById(fileId));
    }

    @Override
    public void createConfigFile(String deployRootDir, Integer deployGroupId) {
        File dir = new File(DeployFileType.CONFIG.getFileName(deployRootDir, ""));
        if (!dir.exists()) {
            dir.mkdirs();//创建目录
        }
        List<DeployConfigFile> fileList = queryConfigFile(deployGroupId, true);
        for (DeployConfigFile deployConfigFile : fileList) {
            String fileName = DeployFileType.CONFIG.getFileName(deployRootDir, deployConfigFile.getFileName());
            decrypt(deployConfigFile);
            FileUtil.createFile(fileName, deployConfigFile.getFileContent());
        }
    }


}
